home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 3: The Continuation / 17-Bit_The_Continuation_Disc.iso / amigan / amigan 23 / middlebutton / middlebutton.asm < prev    next >
Encoding:
Assembly Source File  |  1994-01-27  |  8.6 KB  |  260 lines

  1.         TTL        MiddleButton
  2. *
  3. *******************************************************************************
  4. *                                          *
  5. *    MiddleButton                                  *
  6. *                                          *
  7. *    Copyright (c) 1989 by Michael Sinz    MKSoft Development          *
  8. *                                          *
  9. *    AmigaDOS EXEC release 1.2 or greater...                      *
  10. *                                          *
  11. *******************************************************************************
  12. *                                          *
  13. *    To assemble, I used the assembler that comes with MANX C68K          *
  14. *                                          *
  15. *    It should assemble without any problems on most 680x0 assemblers      *
  16. *    The code is position independant and thus needs an assembler that     *
  17. *    can produce such files.                              *
  18. *                                          *
  19. *******************************************************************************
  20. *                                          *
  21. *    This program installs a handler into the input food chain.          *
  22. *    The handler converts the middle mouse button (for those of you          *
  23. *    with such animals) into a shift key for all mouse events.          *
  24. *                                          *
  25. *    Thus, when you hold the middle button down, you can "SHIFT-SELECT"    *
  26. *    using just the mouse.  Some programs also give you an extended          *
  27. *    select mode when you click the mouse and push the shift key.          *
  28. *    Only mouse events are modified to have the shift key qualifier.          *
  29. *                                          *
  30. *    When you run this program, it will take 80 bytes of system memory     *
  31. *    to install and link in the handler code.  It then exits...          *
  32. *                                          *
  33. *******************************************************************************
  34. *
  35. * The following INCLUDE files are needed to make this program assemble.
  36. * They come with the Amiga Macro-Assembler Package.
  37. *
  38.     NOMLIST                    ; No macro expansion list
  39.     NOCLIST                    ; No conditional list
  40.     NOLIST                    ; No need to list these
  41.     INCLUDE    "EXEC/Types.i"
  42.     INCLUDE    "EXEC/Libraries.i"
  43.     INCLUDE    "EXEC/Interrupts.i"
  44.     INCLUDE    "EXEC/Memory.i"
  45.     INCLUDE    "EXEC/IO.i"
  46.     INCLUDE    "EXEC/Ables.i"
  47.     INCLUDE    "Libraries/DOSextens.i"
  48.     INCLUDE    "Devices/Input.i"
  49.     INCLUDE    "Devices/InputEvent.i"
  50.     LIST                    ; Ok, lets start the listing
  51. *
  52. *******************************************************************************
  53. *
  54. * This is the only fixed address in the system and it even "floats"...
  55. *
  56.         xref    _AbsExecBase
  57. *
  58. *******************************************************************************
  59. *
  60. * Some macros that make calling the system routines easier...
  61. *
  62. CALLSYS        MACRO
  63.         xref    _LVO\1        ; Set the external reference
  64.         CALLLIB    _LVO\1        ; Call the EXEC definied macro
  65.         ENDM
  66. *
  67. *******************************************************************************
  68. *                                          *
  69. * Register usage through this system...                          *
  70. *                                          *
  71. *    a0    - Scrap                                  *
  72. *    a1    - Scrap                                  *
  73. *    a2    - IO Block                              *
  74. *    a3    - MsgPort                              *
  75. *    a4    - Task                                  *
  76. *    a5    - New Memory                              *
  77. *    a6    - ExecBase pointer                          *
  78. *    a7    - Stack pointer...  What else?                      *
  79. *                                          *
  80. *    d0    - Scrap                                  *
  81. *    d1    - Scrap                                  *
  82. *    d2    - Scrap                                  *
  83. *    d3    - Scrap                                  *
  84. *    d4    - Scrap                                  *
  85. *    d5    - Scrap                                  *
  86. *    d6    - Scrap                                  *
  87. *    d7    - Zero...                              *
  88. *                                          *
  89. *******************************************************************************
  90. *
  91. * Now, for the start of the code...
  92. *
  93. MiddleButton:    move.l    _AbsExecBase,a6        ; Get the EXEC library base
  94. *
  95.         clr.l    d7        ; Clear d7...
  96. *
  97.         move.l    d7,a1        ; Clear a1
  98.         CALLSYS    FindTask    ; Get our task pointer...
  99.         move.l    d0,a4        ; Now, move it to a1 for addressing use
  100.         lea    pr_MsgPort(a4),a3
  101.         tst.l    pr_CLI(a4)    ; Check if this is a CLI task...
  102.         bne.s    QuickCLI    ; If so, skip the next section
  103. *
  104. *******************************************************************************
  105. *
  106. * This section deals with starting from the WorkBench...
  107. * It is just here for completeness...
  108. *
  109. QuickWorkBench:    move.l    a3,a0        ; Get message port
  110.         CALLSYS    WaitPort    ; Wait for the WorkBench message...
  111.         move.l    a3,a0        ; ...it's here, so let's get it
  112.         CALLSYS    GetMsg        ; off the message port...
  113.         bra.s    QuickCont    ; ...and go to the continue routine
  114. *
  115. *******************************************************************************
  116. *
  117. * The routine was started from the CLI  (prefered)
  118. * Let's store a NULL pointer so that there is no WB message...
  119. *
  120. QuickCLI:    move.l    d7,d0        ; No reply message...
  121. *
  122. *******************************************************************************
  123. *
  124. * Continue with the Quick initialization
  125. *
  126. QuickCont:
  127.         move.l    d0,-(sp)    ; Save the message pointer...
  128. *
  129.         lea    InputBlock(pc),a2    ; Get the I/O block
  130.         move.b    #NT_MESSAGE,LN_TYPE(a2)    ; initialize it...
  131.         move.w    #IOSTD_SIZE,MN_LENGTH(a2)
  132.         move.l    a3,MN_REPLYPORT(a2)    ; Our reply port...
  133. *
  134.         lea    inputName(pc),a0    ; Get input.device name
  135.         move.l    d7,d0        ; Clear d0
  136.         move.l    d7,d1        ;    and d1
  137.         move.l    a2,a1
  138.         CALLSYS    OpenDevice    ; a1 is still set to the I/O block
  139.         tst.l    d0
  140.         bne.s    abortNoInput
  141. *
  142. *******************************************************************************
  143. *
  144. * We now allocate and copy the handler...
  145. *
  146.         move.l    #CodeSize,d0    ; Size of memory
  147.         move.l    d0,d6        ; Save it...
  148.         move.l    #MEMF_PUBLIC,d1    ; Type of memory
  149.         CALLSYS    AllocMem    ; Get the memory
  150.         move.l    d0,a5        ; Save it...
  151.         tst.l    d0        ; Check it...
  152.         beq.s    NormalExit    ; No memory, no copy...
  153.         move.l    d0,a1        ; Destination...
  154.         lea    StartOfCode(pc),a0    ; Source
  155. CopyLoop:    move.b    (a0)+,(a1)+    ; Copy it...
  156.         dbra    d6,CopyLoop    ; All of it...
  157. *
  158. *******************************************************************************
  159. *
  160. * We also need to add our own input handler into the food chain...
  161. *
  162.         move.l    a5,a0            ; Start of new code...
  163.         add.l    #HandlerOffset,a0    ; Pointer to handler
  164.         move.b    #60,LN_PRI(a0)        ; Handler priority
  165.         move.l    a5,IS_DATA(a0)        ; Handler data
  166.         addq.l    #2,a5            ; Point to code...
  167.         move.l    a5,IS_CODE(a0)        ; Handler code
  168.         move.l    a2,a1            ; Get i/o block
  169.         move.l    a0,IO_DATA(a1)        ; Set the data address...
  170.         move.w    #IND_ADDHANDLER,IO_COMMAND(a1)    ; the ADD command...
  171.         CALLSYS    DoIO            ; All set, handler is running
  172. *
  173. *******************************************************************************
  174. *
  175. * The standard exit routines...
  176. * Close anything that we have opened...
  177. *
  178. NormalExit:
  179.         move.l    a2,a1        ; Get I/O block...
  180.         CALLSYS    CloseDevice    ; Close the thing...
  181. abortNoInput:
  182.         move.l    (sp)+,d0    ; Get that message back
  183.         beq.s    abortNoWB    ; If none, we are done
  184.         move.l    d0,a1        ; Get the pointer ready
  185.         FORBID            ; manual says we must forbid...
  186.         CALLSYS    ReplyMsg    ; ...when returning WB message
  187. abortNoWB:
  188.         rts            ; RTS out of this task...
  189. *
  190. *******************************************************************************
  191. *
  192. * The input block...
  193. *
  194. InputBlock:    ds.b    IOSTD_SIZE
  195. *
  196. *******************************************************************************
  197. *
  198. * This is the mouse accel value...
  199. *
  200. StartOfCode:    dc.w    0        ; Flag value for shift key...
  201. *
  202. *******************************************************************************
  203. *
  204. * This is the handler...  It is the hardest working piece of code here...
  205. *
  206. MyHandler:    move.l    a0,-(sp)    ; We MUST save what we play with...
  207. *
  208. *******************************************************************************
  209. *
  210. * Now, for the handler loop...  We will look at every event that has been given
  211. * to us.
  212. *
  213. HandlerLoop:    cmpi.b    #IECLASS_RAWMOUSE,ie_Class(a0)    ; Check for mouse...
  214.         bne.s    HandlerNext            ; If skip it...
  215. *
  216. *        if IECODE_MBUTTON...    IECODE_UP_PREFIX...
  217.         move.w    ie_Code(a0),d0        ; Get code...
  218.         cmpi.w    #IECODE_MBUTTON,d0    ; Check if button is pushed...
  219.         bne.s    NotDown            ; Middle button not down...
  220. *
  221.         move.w    #IEQUALIFIER_LSHIFT,(a1)    ; Store the left shift
  222.         bra.s    HandlerCont            ; and continue
  223. *
  224. NotDown:    cmpi.w    #(IECODE_MBUTTON+IECODE_UP_PREFIX),d0    ; Button up?
  225.         bne.s    HandlerCont                ; If not, skip
  226.         clr.w    (a1)                    ; Clear code...
  227. *
  228. HandlerCont:    move.w    ie_Qualifier(a0),d0    ; Get qualifier...
  229.         or.w    (a1),d0            ; or in the shift value...
  230.         move.w    d0,ie_Qualifier(a0)    ; Store it...
  231. *
  232. HandlerNext:
  233.         move.l    ie_NextEvent(a0),d0    ; Get next event...
  234.         move.l    d0,a0
  235.         bne.s    HandlerLoop        ; Go back and do this one...
  236. *
  237.         move.l    (sp)+,d0    ; Restore our stuff...  d0=a0...
  238.         rts            ; Done with handler...
  239. *
  240. *******************************************************************************
  241. *
  242. HandlerInfo:    ds.b    IS_SIZE        ; The handler structure...
  243. EndOfCode:
  244. CodeSize    EQU    EndOfCode-StartOfCode
  245. HandlerOffset:    EQU    HandlerInfo-StartOfCode
  246. *
  247. *******************************************************************************
  248. *
  249. * The data section...
  250. *
  251. inputName    dc.b    'input.device',0
  252. *
  253. *******************************************************************************
  254. *
  255. * And, with that we come to the end of another full-length feature staring
  256. * that wonderful MC680x0 and the Amiga system.  Join us again next time
  257. * for more Wonderful World of Amiga...  Until then, keep boinging...
  258. *
  259.         end
  260.